You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This PR adds the QTI Gap Match interaction.
Gap match asks a learner to fill blanks in a passage from a pool of words. The fixtures for it already existed but I added extra examples for the answer specific pools.
What it does
Renders qti-gap-match-interaction with a response pool above the passage and inline blanks in the text
Fill a gap by clicking a word then a gap, or a gap then a word
Drag a word into a gap, between gaps, or back to the pool
Tab reaches each gap and the arrow keys step through its options, so nothing needs a mouse
Clicking a filled gap empties it; dropping onto one replaces what's there
Restores a saved answer and reports it back for scoring
Answer-specific distractor pools
A gap can be fed by its own set of words instead of the whole pool. Picking up a word highlights the gaps that would take it Behavior description:
While dragging, gaps that would reject the word are dimmed
Gaps that already hold a word aren't highlighted, though they can still be replaced
An item with no match-group behaves exactly as before, one pool feeding every gap
qti-answer-specific-pools.webm
Notable details
Gaps are found by walking the passage, since a gap can sit anywhere the author puts it, inside a paragraph, a table cell, a quotation
Gap match writes its pairs word-first, the opposite of match interaction, so useMatchRows gained an option for which end comes first. Match interaction is unaffected.
Gap.vue takes its attributes over rather than inheriting them. An inherited class replaces the component's own root class instead of joining it, which would break both the gap styling and the width classes.
qti-input-width-N sizes a blank to roughly N characters
$\color{rgba(0, 128, 0)}{\textsf{Gap match inside a table example:}}$
Navigate to http://localhost:8000/en/learn/#/qti_sandbox
All of the gap match examples in the sandbox are supported and render
but these examples don't do all what the name implies, some of these were dropped:
Positioning: qti-choices-top/bottom/left/right are ignored, so all four pools sit above their passage instead of beside it.
Container Width: data-choices-container-width is ignored. The apparent width difference comes from the fixture's own qti-layout-col5 / qti-layout-col9 wrappers.
Custom Messages: data-max-selections-message and data-min-selections-message are ignored, and there's no notice yet at all, so nothing is shown when a limit is hit.
AI usage
All unit tests are written by Claude in addition to the extra fixture I added
Pull request description has correctly filled AI usage section & follows our AI guidance:
AI guidance
State explicitly whether you didn't use or used AI & how.
If you used it, ensure that the PR is aligned with Using AI as well as our DEEP framework. DEEP asks you:
Disclose — Be open about when you've used AI for support.
Engage critically — Question what is generated. Review code for correctness and unnecessary complexity.
Edit — Review and refine AI output. Remove unnecessary code and verify it still works after your edits.
Process sharing — Explain how you used the AI so others can learn.
Examples of good disclosures:
"I used Claude Code to implement the component, prompting it to follow the pattern in ComponentX. I reviewed the generated code, removed unnecessary error handling, and verified the tests pass."
"I brainstormed the approach with Gemini, then had it write failing tests for the feature. After reviewing the tests, I used Claude Code to generate the implementation. I refactored the output to reduce verbosity and ran the full test suite."
Also check that issue requirements are satisfied & you ran pre-commit locally.
Pull requests that don't follow the guidelines will be closed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds the QTI Gap Match interaction.
Gap match asks a learner to fill blanks in a passage from a pool of words. The fixtures for it already existed but I added extra examples for the answer specific pools.
What it does
qti-gap-match-interactionwith a response pool above the passage and inline blanks in the textAnswer-specific distractor pools
A gap can be fed by its own set of words instead of the whole pool. Picking up a word highlights the gaps that would take it
Behavior description:
qti-answer-specific-pools.webm
Notable details
Gap.vuetakes its attributes over rather than inheriting them. An inherited class replaces the component's own root class instead of joining it, which would break both the gap styling and the width classes.qti-input-width-Nsizes a blank to roughly N charactersReferences
Reviewer guidance
http://localhost:8000/en/learn/#/qti_sandboxbut these examples don't do all what the name implies, some of these were dropped:
AI usage
All unit tests are written by Claude in addition to the extra fixture I added